package withouther.system.core.security.handle;

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.ResponseUtil;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import withouther.system.core.result.WhResult;
import withouther.system.core.util.SecurityUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;

/**
 * @Classname WhAuthenticationEntryPointImpl
 * @Description 用来解决认证过的用户访问无权限资源时的异常
 * @Author tzq
 * @Date 2020/03/19 5:35 下午
 * @Version 1.0
 */
@Component
@Slf4j
public class WhAuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable {

    private static final long serialVersionUID = -8970718410437077606L;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
        String message = "请求访问: " + request.getRequestURI() + " 接口， 经jwt认证失败，无法访问系统资源.";
        SecurityUtil.write(response, getMessage(message, e));
    }

    private WhResult getMessage(String message, AuthenticationException exception) {

        if (exception instanceof BadCredentialsException ||
                exception instanceof UsernameNotFoundException) {
            message = "用户名或密码错误";
        } else if (exception instanceof LockedException) {
            message = "账户被锁定，请联系管理员!";
        } else if (exception instanceof CredentialsExpiredException) {
            message = "账户被锁定，请联系管理员!";
        } else if (exception instanceof AccountExpiredException) {
            message = "账户过期，请联系管理员!";
        } else if (exception instanceof DisabledException) {
            message = "账户被禁用，请联系管理员!";
        } else {
            return WhResult.fail(401, message);
        }
        return WhResult.fail(500, message);
    }
}
